package com.java.exer.mycode;


/*
  
boolean addAll(int index, MyList c) 
将指定集合中的所有元素插入到此列表中的指定位置（可选操作）。  
。  
boolean containsAll(MyList c) 
如果此列表包含指定 集合的所有元素，则返回true。  
int indexOf(Object o) 
返回此列表中指定元素的第一次出现的索引，如果此列表不包含元素，则返回-1。  
int lastIndexOf(Object o) 
返回此列表中指定元素的最后一次出现的索引，如果此列表不包含元素，则返回-1。  
boolean remove(Object o) 
从列表中删除指定元素的第一个出现（如果存在）（可选操作）。  
boolean removeAll(MyList c) 
从此列表中删除包含在指定集合中的所有元素（可选操作）。  
Object set(int index, Object element) 
用指定的元素（可选操作）替换此列表中指定位置的元素。  
List subList(int fromIndex, int toIndex) 
返回此列表中指定的 fromIndex （含）和 toIndex之间的视图。  
Object[] toArray() 
以正确的顺序（从第一个到最后一个元素）返回一个包含此列表中所有元素的数组。  
// */
public class MyList_1 {
    // 记录元素个数
    private int size;
    // 记录第一个元素的位置(地址)
    private com.java.exer.mycode.ListNode firstNode;

    public MyList_1() {
        super();
    }

    /*
     * 添加元素到链表结尾
     *
     */
    public void add(Object element) {
        // 创建一个链表
        com.java.exer.mycode.ListNode newNode = new com.java.exer.mycode.ListNode(size, element);
        // 判断这个链表是否为空
        if (size == 0) {
            this.firstNode = newNode;
        }
        // 如果不为空 向最后的元素添加 找到最后一个元素的节点
        else {
            com.java.exer.mycode.ListNode lastNode = getLastNode();
            lastNode.setNext(newNode);

        }
        size++;
    }

    /*
     * 找最后一个节点
     *
     */
    public com.java.exer.mycode.ListNode getLastNode() {

        return getIndexNode(size - 1);
    }

    public void add(int index, Object element) {
        // 创建一个新的链表节点
        com.java.exer.mycode.ListNode newNode = new com.java.exer.mycode.ListNode(index, element);

        // 首先判断是否越界
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException();
        }
        // 判断这个链表是否为空 判断添加的位置是否是末位置
        if (index == size) {
            this.add(element);
        }
        // 判断添加的位置是否是首位置
        else if (index == 0) {
            // 获取后续链表节点的引用
            com.java.exer.mycode.ListNode followNode = firstNode;
            // 修改节点
            changeIndex(followNode, true);
            // 至少有一个元素
            firstNode = newNode;
            // 这个新添加的元素要获取后续元素的节点
            newNode.setNext(followNode);
            size++;
        }
        // 在中间位置
        else {
            // 至少有两个节点 向中间添加
            com.java.exer.mycode.ListNode upNode = getIndexNode(index - 1);

            com.java.exer.mycode.ListNode dowNode = getIndexNode(index);

            // 累加一下index
            changeIndex(dowNode, true);
            // 改变前后节点的引用
            upNode.setNext(newNode);
            newNode.setNext(dowNode);
            size++;

        }

    }

    /*
     * 修改位置 node 要添加的位置的元素 addFlag： true 节点后移(添加) false 节点前移(删除)
     */
    private void changeIndex(com.java.exer.mycode.ListNode node, Boolean addFlag) {

        while (node != null) {
            if (addFlag) {
                // 将原本在这个位置的元素Index+1
                node.setIndex(node.getIndex() + 1);
            } else {
                // 将原本在这个位置的元素Index+1
                node.setIndex(node.getIndex() - 1);
            }
            node = node.getNext();
        }

    }

    /*
     * 获得指定位置的节点
     *
     */
    public com.java.exer.mycode.ListNode getIndexNode(int index) {
        // 判断这个位置是否合法
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException();
        }
        //
        com.java.exer.mycode.ListNode whileNode = firstNode;
        while (whileNode.getIndex() != index) {
            whileNode = whileNode.getNext();
        }
        return whileNode;

    }

    /*
     * 获得指定位置的元素
     */
    public Object get(int index) {
        com.java.exer.mycode.ListNode listNode = getIndexNode(index);
        return listNode.getElement();
    }

    /*
     * 打印这个链表
     */
    @Override
    public String toString() {
        StringBuffer sbfBuffer = new StringBuffer("[");
        for (int i = 0; i < size; i++) {
            sbfBuffer.append(this.get(i));
            if (i != size - 1) {
                sbfBuffer.append(", ");
            }
        }

        return sbfBuffer.append("]").toString();
    }


    /*
     * 删除该列表中指定位置的元素
     *
     */
    public Object remove(int index) {
        // 判断这个index是否合法
        if (index < 0 || index > size - 1) {
            throw new IndexOutOfBoundsException();
        }
        // 获取返回的结果
        Object resultObject = getIndexNode(index).getElement();
        // 删除开头元素
        if (index == 0) {
            // 接收下一个节点
            com.java.exer.mycode.ListNode nextNode = getIndexNode(index + 1);
            // 改变他的index（减）
            changeIndex(nextNode, false);
            // 把这个节点保存为第一个节点
            firstNode = nextNode;

        }
        // 删除尾部元素
        else if (index == size - 1) {
            // 判断他是否只有一个元素
            if (size == 1) {
                firstNode = null;
            }
            // 如果不是一个元素
            else {
                com.java.exer.mycode.ListNode node = getIndexNode(size - 2);
                node.setNext(null);
            }
        }
        // 删除中间元素
        else {
            // 肯定有三个以上元素 记录上一个节点信息
            com.java.exer.mycode.ListNode upNode = getIndexNode(index - 1);
            // 记录下一个节点信息
            com.java.exer.mycode.ListNode dowNode = getIndexNode(index + 1);
            // 改变Index
            changeIndex(dowNode, false);
            upNode.setNext(dowNode);
        }
        size--;
        return resultObject;
    }

    /*
     * 如果包含指定元素就  返回 true  否则返回false
     *
     * */
    public boolean contine(Object o) {
        for (int i = 0; i < size; i++) {
            if (get(i).equals(o)) {
                return true;
            }
        }
        return false;

    }

    /*
     * 仅保留此列表中包含在指定集合中的元素（可选操作）。
     *
     * */
    public void retainAll(MyList_1 o) {
        for (int i = size - 1; i >= 0; i--) {
            if (!o.contine(get(i))) {
                remove(i);
                size--;
            }
        }
    }

    /*
     * 返回此列表中的元素数
     *
     * */
    public int size() {
        int count = 0;
        for (int i = 0; i < size; i++) {
            get(i);
            count++;
        }
        return count;
    }

    //	public int  size() {
//		return size
//		
//	}
    /*
     * 如果此列表不包含元素，则返回 truObject
     * */
    public boolean isEmpty(MyList_1 myList) {
        if (myList.size == 0) {
            return false;
        }
        return true;
    }

    /*
     * 从此列表中删除所有元素（可选操作）
     *
     * */
    public void clear() {
        if (this.size == 0) {
            throw new NullPointerException();
        }
        for (int i = 0; i < size; i++) {
            remove(i);
            size--;
        }
    }

    /*
     *
     *	按指定集合的迭代器（可选操作）返回的顺序将指定集合中的所有元素附加到此列表的末尾。
     *
     * */
    public boolean addAll(MyList_1 c) {
        //判断指定集合是否为空
        if (c.size() == 0) {
            throw new NullPointerException();
        }

        for (int i = 0; i < c.size(); i++) {
            this.add(c.get(i));
            size++;
        }

        return true;
    }
}
